package com.example.uavstatus;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;

import dji.common.error.DJIError;
import dji.common.error.DJISDKError;
import dji.common.flightcontroller.FlightControllerState;
import dji.common.flightcontroller.LocationCoordinate3D;
import dji.sdk.base.BaseComponent;
import dji.sdk.base.BaseProduct;
import dji.sdk.battery.Battery;
import dji.sdk.flightcontroller.FlightController;
import dji.sdk.products.Aircraft;
import dji.sdk.sdkmanager.DJISDKInitEvent;
import dji.sdk.sdkmanager.DJISDKManager;
import dji.sdk.sdkmanager.DJISDKManager.SDKManagerCallback;

public class DJIConnection {
    private static final String TAG = "DJIConnection";

    private final Context context;
    private final SharedPreferences preferences;

    private BaseProduct product;
    private DatagramSocket udpSendSocket;
    private DatagramSocket udpReceiveSocket;
    private InetAddress serverAddress;
    private boolean isListening = true;
    private Handler mainHandler = new Handler(Looper.getMainLooper());

    private String serverIp;
    private int serverPort;
    private int controlPort;

    public DJIConnection(Context context, SharedPreferences preferences) {
        this.context = context;
        this.preferences = preferences;

        // 从设置中加载配置
        loadSettings();
        initUdpConnection();
    }

    private void loadSettings() {
        serverIp = preferences.getString("server_ip", "192.168.1.11");
        controlPort = preferences.getInt("control_port", 4321);
        serverPort = preferences.getInt("data_port", 1234);

        Log.d(TAG, "加载设置: IP=" + serverIp +
                ", 控制端口=" + controlPort +
                ", 数据端口=" + serverPort);
    }

    private void initUdpConnection() {
        // 初始化发送Socket
        new Thread(() -> {
            try {
                serverAddress = InetAddress.getByName(serverIp);
                udpSendSocket = new DatagramSocket();
                udpSendSocket.setSoTimeout(1000);
                Log.d(TAG, "UDP发送客户端初始化成功: " + serverIp + ":" + serverPort);
            } catch (Exception e) {
                Log.e(TAG, "UDP发送初始化失败: " + e.getMessage(), e);
            }
        }).start();

        // 初始化接收Socket（控制端口）
        new Thread(this::startControlListener).start();
    }

    private void startControlListener() {
        try {
            udpReceiveSocket = new DatagramSocket(controlPort);
            udpReceiveSocket.setSoTimeout(1000);
            Log.d(TAG, "UDP控制监听启动，端口: " + controlPort);

            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

            while (isListening) {
                try {
                    udpReceiveSocket.receive(packet);
                    String command = new String(
                            packet.getData(),
                            0,
                            packet.getLength(),
                            StandardCharsets.UTF_8
                    ).trim();

                    Log.d(TAG, "收到控制命令: " + command);

                    if ("解锁".equals(command)) {
                        unlockDrone();
                    }
                } catch (IOException e) {
                    // 超时是正常的，继续循环
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "UDP控制监听失败: " + e.getMessage(), e);
        } finally {
            if (udpReceiveSocket != null && !udpReceiveSocket.isClosed()) {
                udpReceiveSocket.close();
            }
        }
    }

    public void initSDK() {
        DJISDKManager.getInstance().registerApp(context, new SDKManagerCallback() {
            @Override
            public void onRegister(DJIError error) {
                if (error == DJISDKError.REGISTRATION_SUCCESS) {
                    Log.d(TAG, "SDK注册成功");
                    updateProductConnection();
                } else {
                    Log.e(TAG, "SDK注册失败: " +
                            (error != null ? error.getDescription() : "未知错误"));
                }
            }

            @Override
            public void onProductConnect(BaseProduct baseProduct) {
                Log.d(TAG, "产品已连接");
                product = baseProduct;
                registerStatusListeners();
            }

            @Override
            public void onProductDisconnect() {
                Log.d(TAG, "产品已断开");
                product = null;
                sendUdpData("STATUS", "设备已断开");
            }

            @Override
            public void onProductChanged(BaseProduct baseProduct) {
                Log.d(TAG, "产品已更换");
                product = baseProduct;
                registerStatusListeners();
            }

            @Override
            public void onComponentChange(BaseProduct.ComponentKey componentKey,
                                          BaseComponent oldComponent,
                                          BaseComponent newComponent) {
                Log.d(TAG, "组件变更: " + componentKey);
            }

            @Override
            public void onInitProcess(DJISDKInitEvent event, int progress) {
                Log.d(TAG, "SDK初始化进度: " + event + " - " + progress + "%");
            }

            @Override
            public void onDatabaseDownloadProgress(long current, long total) {
                Log.d(TAG, "数据库下载进度: " + current + "/" + total);
            }
        });
    }

    private void updateProductConnection() {
        BaseProduct currentProduct = DJISDKManager.getInstance().getProduct();
        if (currentProduct != null && currentProduct.isConnected()) {
            product = currentProduct;
            registerStatusListeners();
            sendUdpData("STATUS", "设备已连接");
        } else {
            product = null;
            sendUdpData("STATUS", "等待设备连接");
        }
    }

    private void registerStatusListeners() {
        if (product == null) {
            Log.w(TAG, "产品未连接，无法注册监听器");
            return;
        }

        // 1. 电池状态监听
        Battery battery = product.getBattery();
        if (battery != null) {
            battery.setStateCallback(state -> {
                if (state != null) {
                    sendUdpData("BATTERY", state.getChargeRemainingInPercent() + "%");
                }
            });
        } else {
            Log.w(TAG, "无法获取电池对象");
        }

        // 2. 飞行控制器状态监听
        if (product instanceof Aircraft) {
            Aircraft aircraft = (Aircraft) product;
            FlightController flightController = aircraft.getFlightController();
            if (flightController != null) {
                flightController.setStateCallback(state -> {
                    if (state != null) {
                        // GPS状态
                        LocationCoordinate3D location = state.getAircraftLocation();
                        if (location != null) {
                            sendUdpData("GPS",
                                    String.format("Lat:%.6f,Lon:%.6f",
                                            location.getLatitude(),
                                            location.getLongitude()));
                            sendUdpData("ALTITUDE", String.format("%.1fm", location.getAltitude()));
                        }

                        // 速度状态
                        sendUdpData("SPEED",
                                String.format("X:%.1f Y:%.1f Z:%.1f m/s",
                                        state.getVelocityX(),
                                        state.getVelocityY(),
                                        state.getVelocityZ()));

                        // 解锁状态
                        sendUdpData("ARMED", state.isFlying() ? "是" : "否");
                    }
                });
            } else {
                Log.w(TAG, "无法获取飞行控制器");
            }
        }
    }

    private void sendUdpData(String key, String value) {
        // 使用后台线程发送UDP数据
        new UdpSendTask().execute(key, value);
    }

    private class UdpSendTask extends AsyncTask<String, Void, Void> {
        @Override
        protected Void doInBackground(String... params) {
            if (params.length < 2 || udpSendSocket == null || serverAddress == null) {
                return null;
            }

            String key = params[0];
            String value = params[1];
            String message = String.format("%s:%s", key, value);

            try {
                byte[] sendData = message.getBytes(StandardCharsets.UTF_8);
                DatagramPacket sendPacket = new DatagramPacket(
                        sendData,
                        sendData.length,
                        serverAddress,
                        serverPort
                );

                udpSendSocket.send(sendPacket);
                Log.d(TAG, "UDP发送成功: " + message);
            } catch (IOException e) {
                Log.e(TAG, "UDP发送失败: " + e.getMessage());
            }
            return null;
        }
    }

    private void unlockDrone() {
        if (!(product instanceof Aircraft)) {
            sendUdpData("ERROR", "非飞行器产品");
            return;
        }

        Aircraft aircraft = (Aircraft) product;
        FlightController flightController = aircraft.getFlightController();
        if (flightController == null) {
            sendUdpData("ERROR", "无法获取飞行控制器");
            return;
        }

        // 在主线程执行解锁操作
        mainHandler.post(() -> {
            // 检查是否可以解锁
            FlightControllerState state = flightController.getState();
            if (state == null) {
                sendUdpData("ERROR", "无法获取飞行状态");
                return;
            }

            if (state.isFlying()) {
                sendUdpData("ERROR", "无人机已在飞行中");
                return;
            }

            // 执行解锁
            flightController.startTakeoff(error -> {
                if (error == null) {
                    sendUdpData("STATUS", "解锁成功");
                } else {
                    sendUdpData("ERROR", "解锁失败: " + error.getDescription());
                }
            });
        });
    }

    public void release() {
        Log.d(TAG, "释放资源");
        // 停止监听线程
        isListening = false;

        // 清理资源
        if (product != null) {
            if (product.getBattery() != null) {
                product.getBattery().setStateCallback(null);
            }

            if (product instanceof Aircraft) {
                Aircraft aircraft = (Aircraft) product;
                if (aircraft.getFlightController() != null) {
                    aircraft.getFlightController().setStateCallback(null);
                }
            }
        }

        // 关闭UDP连接
        new Thread(() -> {
            if (udpSendSocket != null && !udpSendSocket.isClosed()) {
                udpSendSocket.close();
            }
            if (udpReceiveSocket != null && !udpReceiveSocket.isClosed()) {
                udpReceiveSocket.close();
            }
            Log.d(TAG, "UDP连接已关闭");
        }).start();

        // 释放SDK资源
        DJISDKManager.getInstance().destroy();
    }
}